package com.insightfullogic.java8.examples.chapter3;

import com.insightfullogic.java8.examples.chapter1.Artist;
import com.insightfullogic.java8.examples.chapter1.SampleDataCN;
import com.insightfullogic.java8.examples.chapter1.Track;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.lang.Character.isDigit;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;

/**
 * @author : wushikai
 * <p>
 * date : 2021-03-26
 * 书上实例;
 */
public class BookExample {


    /**
     * 例3-9　使用map操作将字符串转换为大写形式
     */
    public static void list2UpperCase() {
        //Lambda can be replaced with method reference  这个报黄 是想告诉你 可以使用方法引用;
        List<String> collected = Stream.of("a", "b", "hello").map(str -> str.toUpperCase()).collect(toList());
        System.out.println(collected.toString());

        // 当 Function<T,R> 中的 T 类型 有直接的实现方法时, 直接就可以使用 方法引用;
        collected = Stream.of("a", "b", "hello").map(String::toUpperCase).collect(toList());
        System.out.println(collected.toString());

    }



    /**
     *
     *例3-11展示了 filter 的用法 去过滤 开头是 数字的 字符串;
     *
     * */

    public  static void beginWithNum ( ){
        List<String> beginningWithNumbers
                = Stream.of("a", "1abc", "abc1")
                .filter(value -> isDigit(value.charAt(0)))
                .collect(toList());

        System.out.println(beginningWithNumbers.toString());

    }




    /**
     * 例3-13　使用Stream查找最短曲目
     *
     * */
    public  static void findShortestSong ( ){
        List<Track> tracks = asList(new Track("Bakai", 524),
                new Track("Violets for Your Furs", 378),
                new Track("Time Was", 451));

        Track shortestTrack = tracks.stream().min(Comparator.comparing(Track::getLength)).get();

        System.out.println(shortestTrack.toString());
    }

    /**
     * 例3-16　使用reduce求和  注意 reduce 有多个重载方法;
     * */
    public  static void reduce2Sum ( ){
        int count = Stream.of(1, 2, 3).reduce(0, (acc, element) -> acc + element);  //将两个参数相加，acc是累加器，保存着当前的累加结果。
        System.out.println(count );
    }


    /**
     * 例3-17　展开reduce操作
     * */
    public  static void reduce2SumExpand ( ){
        BinaryOperator<Integer> accumulator = (acc, element) -> acc + element;  // 这个 lambda 表达式 重写了 apply 方法 ;
        int count = accumulator.apply(  accumulator.apply(accumulator.apply(0, 1),2)   ,   3);
        System.out.println(count);

    }

    /**
     * 例3-17　展开reduce操作
     * 有时候 lambda 表达式 总是令人头痛;  需要好好分析一番
     * */
    public  static void reduce2SumExpand_a ( ){

        BinaryOperator<Integer> accumulator = new BinaryOperator<Integer>() {
            @Override
            public Integer apply(Integer integer, Integer integer2) {

                return  integer + integer2;
            }
        };
        int count = accumulator.apply(  accumulator.apply(accumulator.apply(0, 1),2)   ,   3);
        //  0   +1     +2    +3
        System.out.println(count);
    }




    /**
     * 简单 ArrayList 求和演示;
     * */
    public  static void getSum ( ){
        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(1);
        integers.add(2);
        integers.add(3);
        Integer integer = integers.stream().reduce((acc, element) -> acc + element).get();
        System.out.println(integer);
    }

    /**
     * 再探 流 的 collect() 方法
     * */
    public  static void discussCollector ( ){
        /*  使用类名去调用和new 对象去调用有何区别 */
        Stream<Artist> artistStream =  SampleDataCN.threeArtists();
        Set<String> collect = artistStream.map(Artist::getName).collect(Collectors.toSet());


    }











    public static void main(String[] args){

        getSum();


    }





}
